import Player from './Player';
import Global from './settings';
import { getDictKeyList, getDictValueList, getTime, getColorNode } from './support';
import { ResManager } from './custom/ResManager';
import GameEvent from './custom/GameEvent';

// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html


let UI_FONT = "font"
let UI_FONT_SIZE = Global.UI_FONT_SIZE
let TEXT_COLOR_SELECTED = Global.TEXT_COLOR_SELECTED
let TEXT_COLOR = Global.TEXT_COLOR
let BAR_COLOR_SELECTED = Global.BAR_COLOR_SELECTED
let BAR_COLOR = Global.BAR_COLOR
let UPGRADE_BG_COLOR_SELECTED = Global.UPGRADE_BG_COLOR_SELECTED
let UI_BG_COLOR = Global.UI_BG_COLOR
let UI_BORDER_COLOR = Global.UI_BORDER_COLOR

export default class UpGrade {

    font : cc.Font
    player : Player

    width
    height
    selection_index
    selection_time
    can_move

    attribute_nr
    attribute_names
    max_values

    item_list
    current_time = 0

	parent : cc.Node

    constructor(player : Player) {
		// general setup 

		this.parent = cc.find('Canvas/map/UI_UpGrade')

		this.player = player
		this.attribute_nr = getDictKeyList(player.stats).length
		this.attribute_names = getDictKeyList(player.stats)
		this.max_values = getDictValueList(player.max_stats)
		this.font = ResManager.getInstance().getRes()[UI_FONT]

		// item creation
		this.height = cc.winSize.height * 0.8
		this.width = cc.winSize.width / 6
		this.create_items()

		// selection system 
		this.selection_index = 0
		this.selection_time = null
		this.can_move = true

		cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.input, this)
        cc.director.on(GameEvent.game_pad_down, (key)=>{
            this.input({keyCode:key})
        }, this)

    }

    create_items() {
        this.item_list = []

		for(let index =0; index<this.attribute_nr; index++) {
			// horizontal position
			let full_width = cc.winSize.width
			let increment = full_width / this.attribute_nr
			let left = (index * increment) + (increment - this.width) / 2 + (-cc.winSize.width/2)
			
			// vertical position 
			// let top = cc.winSize.height * 0.1
			let bottom = -this.height / 2

			// create the object 
			let item = new Item(left,bottom,this.width,this.height,index,this.font)
			this.item_list.push(item)
			this.parent.addChild(item)
        }
    }

    selection_cooldown() {
        if(!this.can_move) {
            this.current_time = getTime()
            if(this.current_time - this.selection_time >= 300) {
                this.can_move = true
            }
        }
    }

    display() {

		this.parent.active = true

		this.selection_cooldown()

        for(let index=0; index<this.item_list.length; index++) {
			// get attributes
            let item = this.item_list[index]
			let name = this.attribute_names[index]
			let value = this.player.get_value_by_index(index)
			let max_value = this.max_values[index]
			let cost = this.player.get_cost_by_index(index)
			item.display(this.selection_index,name,value,max_value,cost)
        }
    }

	hide() {
		this.parent.active = false
	}

    input(event) {


        let code = event.keyCode
		
		if(code == cc.macro.KEY.m) {
			if(this.parent.active) {
				cc.director.emit(GameEvent.key_menu)
			}
			return
		}

		if(this.can_move) {
			if(code == cc.macro.KEY.right && this.selection_index < this.attribute_nr - 1) {
				this.selection_index += 1
				this.can_move = false
				this.selection_time = getTime()
            } else if(code == cc.macro.KEY.left && this.selection_index >= 1) {
				this.selection_index -= 1
				this.can_move = false
				this.selection_time = getTime()
            }

			if(code == cc.macro.KEY.space) {
				this.can_move = false
				this.selection_time = getTime()
				this.item_list[this.selection_index].trigger(this.player)
            }
        }
    }

}


class Item extends cc.Node {

    rect : cc.Rect
    index
    font : cc.Font
    
	titleLabel : cc.Label
	costLabel : cc.Label

	lineNode : cc.Node
	barNode : cc.Node
	bgNode : cc.Node
	borderNode : cc.Node

    constructor(l,b,w,h,index,font) {

		super()

        this.rect = new cc.Rect(l,b,w,h)
		this.index = index
		this.font = font

		this.initUi()
    }

	initUi() {

		this.create_bg()
		this.create_bar()
		this.create_names()

		this.setPosition(this.rect.center.x, 0)
	}

	create_names() {
		// title text
		let titleNode = new cc.Node()
		this.titleLabel = titleNode.addComponent(cc.Label)
		this.titleLabel.font = this.font
		this.titleLabel.fontSize = UI_FONT_SIZE
		titleNode.setContentSize(200, 30)

		// cost text
		let costNode = new cc.Node()
		this.costLabel = costNode.addComponent(cc.Label)
		this.costLabel.font = this.font
		this.costLabel.fontSize = UI_FONT_SIZE
		costNode.setContentSize(200, 30)
		
		let x1 = 0
		let y1 = this.rect.yMax - titleNode.getContentSize().height/2 - 30
		titleNode.setPosition(x1, y1)

		let x2 = 0
		let y2 = this.rect.yMin - costNode.getContentSize().height/2 + 30
		costNode.setPosition(x2, y2)

		this.addChild(titleNode)
		this.addChild(costNode)
	}

	create_bar() {

		let top = this.rect.yMax - 60
		let bottom = this.rect.yMin + 60
		

		let full_height = top - bottom

		let lineNode = getColorNode(5, full_height)
		this.lineNode = lineNode

		let barNode = getColorNode(30, 10)
		this.barNode = barNode

		this.addChild(lineNode)
		this.addChild(barNode)
	}

	create_bg() {
		
		let bgNode = getColorNode(this.rect.width-4, this.rect.height-4)
		this.bgNode = bgNode

		let borderNode = getColorNode(this.rect.width, this.rect.height)
		this.borderNode = borderNode

		this.addChild(borderNode)
		this.addChild(bgNode)
	}


    display_names(name,cost,selected) {
		let color = selected ? TEXT_COLOR_SELECTED : TEXT_COLOR

		this.titleLabel.string = name
		this.titleLabel.node.color = new cc.Color().fromHEX(color)

		this.costLabel.string = "" + Math.floor(cost)
		this.costLabel.node.color = new cc.Color().fromHEX(color)
    }

	display_bar(value,max_value,selected) {

		let color = selected ? BAR_COLOR_SELECTED : BAR_COLOR

		let full_height = this.lineNode.height
		let relative_number = (value / max_value) * full_height

		this.lineNode.color = new cc.Color().fromHEX(color)
		this.barNode.color = new cc.Color().fromHEX(color)

		let y = this.lineNode.y - full_height/2 + relative_number
		this.barNode.setPosition(0, y)
	}

	trigger(player : Player) {
		let upgrade_attribute = getDictKeyList(player.stats)[this.index]

		if(player.exp >= player.upgrade_cost[upgrade_attribute] && player.stats[upgrade_attribute] < player.max_stats[upgrade_attribute]) {
			player.exp -= player.upgrade_cost[upgrade_attribute]
			player.stats[upgrade_attribute] *= 1.2
			player.upgrade_cost[upgrade_attribute] *= 1.4
		}

		if(player.stats[upgrade_attribute] > player.max_stats[upgrade_attribute]) {
			player.stats[upgrade_attribute] = player.max_stats[upgrade_attribute]
		}
	}

	display(selection_num,name,value,max_value,cost) {
		let bgColor = this.index == selection_num ? UPGRADE_BG_COLOR_SELECTED : UI_BG_COLOR

		this.bgNode.color = new cc.Color().fromHEX(bgColor)
		this.borderNode.color = new cc.Color().fromHEX(UI_BORDER_COLOR)

		this.display_bar(value,max_value,this.index == selection_num)
		this.display_names(name,cost,this.index == selection_num)
	}
}